#ifndef Tab2D_cxx
#define Tab2D_cxx

#include "Tab2D.h"

namespace FPTK
{
template<class T>
Tab2D<T>::Tab2D(int _R,int _C)
{
    try{
    if(_R<=0 ||_C<=0)
    {
        R=-1;
        C=-1;
        tab=NULL;
        Exception ex("Tab2D::Constructor","Size must be positive");
        throw ex;
    }
    Exception op("a","b");
    R=_R;
    C=_C;
    tab=new T[R*C];
    }
    catch(Exception ex)
    {
       std::cout<<ex<<std::endl;
    }
    catch(std::bad_alloc &ba)
    {
        std::cout<<"Tab2D::Constructor:"<<ba.what()<<std::endl;
    }
}


template<class T>
Tab2D<T>::~Tab2D()
{
delete []tab;
}

template<class T>
Tab2D<T>::Tab2D(const Tab2D<T>& t)
{
    R = t.GetNbRow ();
    C = t.GetNbColumn ();
    tab=new T[R*C];
   for(int i=0;i<R;i++)
   {
      for(int j=0;j<C;j++)
      {
          SetElement(t.GetElement(i,j),i,j);
      }
   }
}


template<class T>
const T Tab2D<T>::GetElement(int i,int j) const
{
    
    Exception ex("Tab2D::GetElement","Position must be positive and smaller than the size of the Tab");
    if(i<0 || i>=R || j<0 || j>=C) throw ex;
return *(tab+i*C+j);
}


template<class T>
void Tab2D<T>::SetElement(T value,int i,int j)
{
Exception ex("Tab2D::GetElement","Position must be positive and smaller than the size of the Tab");
if(i<0 || i>=R || j<0 || j>=C) throw ex;
*(tab+i*C+j)=value;
}

template<class T>
void Tab2D<T>::Zeros()
{
Fill(T(0));
}

template<class T>
void Tab2D<T>::Fill(T _var)
{
      for(int i=0;i<R;i++)
      {
         for(int j=0;j<C;j++)
         {
            SetElement(_var,i,j);
         }
      }
}

//template<class T>
//int Tab2D<T>::GetNbColumn()
//{
//    return C;
//}

//template<class T>
//int Tab2D<T>::GetNbRow()
//{
//    return R;
//}

template<class T>
const int Tab2D<T>::GetNbColumn() const
{
    return C;
}

template<class T>
const int Tab2D<T>::GetNbRow() const
{
    return R;
}

template<class T>
bool Tab2D<T>::operator==(const Tab2D<T>& t2) const
{
   Exception ex("Tab2::operator==","Tables doesn\'t have the same size");
   if(t2.GetNbColumn()!=C || t2.GetNbRow()!=R) throw ex;
   for(int i=0;i<R;i++)
   {
      for(int j=0;j<C;j++)
      {
          if(GetElement(i,j)!=t2.GetElement(i,j)) return false;
      }
   }
   return true;
}

template<class T>
bool Tab2D<T>::operator!=(const Tab2D<T>& t2) const
{
   return ~((*this)==t2);
}

template<class T>
Tab2D<T> Tab2D<T>::operator=(const Tab2D<T>& t2)
{
   Exception ex("Tab2::operator=","Tables doesn\'t have the same size");
   if(t2.GetNbColumn()!=C || t2.GetNbRow()!=R) throw ex;
   for(int i=0;i<R;i++)
   {
      for(int j=0;j<C;j++)
      {
          SetElement(t2.GetElement(i,j),i,j);
      }
   }
   return *this;
}


}//end namespace FPTK

#endif